<?php

/**
 * Webman gRPC服务端示例
 * 
 * 本示例展示了如何使用Webman gRPC扩展包创建服务端，包括：
 * 1. 基本的gRPC服务
 * 2. 拦截器使用
 * 3. 流式响应
 * 4. 事件监听
 * 5. 性能监控
 */

require_once __DIR__ . '/vendor/autoload.php';

use WebmanGrpc\BaseService;
use WebmanGrpc\GrpcManager;
use WebmanGrpc\Interceptor\ServerInterceptorInterface;
use WebmanGrpc\Event\EventBus;
use WebmanGrpc\Event\Event;
use WebmanGrpc\Event\EventListenerInterface;

// 创建自定义拦截器
class LoggingInterceptor implements ServerInterceptorInterface
{
    public function intercept($request, $context, $next)
    {
        // 前置处理
        $startTime = microtime(true);
        $method = $context->method;
        echo "[$method] 请求开始\n";
        
        // 调用下一个处理器
        try {
            $response = $next($request, $context);
            
            // 后置处理
            $endTime = microtime(true);
            $duration = $endTime - $startTime;
            echo "[$method] 请求成功，耗时: " . round($duration * 1000, 2) . "ms\n";
            
            return $response;
        } catch (\Exception $e) {
            // 错误处理
            $endTime = microtime(true);
            $duration = $endTime - $startTime;
            echo "[$method] 请求失败，耗时: " . round($duration * 1000, 2) . "ms，错误: " . $e->getMessage() . "\n";
            
            throw $e;
        }
    }
}

// 创建事件监听器
class ServiceEventListener implements EventListenerInterface
{
    public function handle($event): void
    {
        echo "服务事件: {$event->getName()}, 数据: " . json_encode($event->getData()) . "\n";
    }
    
    public function getPriority(): int
    {
        return 100;
    }
}

// 创建示例服务
class ExampleService extends BaseService
{
    /**
     * 简单调用方法
     */
    public function SimpleMethod($request, $context)
    {
        // 发布事件
        $eventBus = EventBus::getInstance();
        $event = new Event('service.request', [
            'method' => 'SimpleMethod',
            'data' => $request->getName() ?? 'Unknown',
        ]);
        $eventBus->publish($event);
        
        // 创建响应
        // 注意：这里使用假设的响应类，实际使用时需要替换为您的Protobuf生成的类
        // $response = new Helloworld\HelloReply();
        // $response->setMessage('Hello ' . $request->getName());
        
        echo "处理SimpleMethod请求\n";
        
        // 返回响应
        // return $response;
        
        // 由于没有实际的Protobuf类，这里返回一个模拟的响应
        return ['message' => 'Hello ' . ($request->getName() ?? 'World')];
    }
    
    /**
     * 服务端流方法
     */
    public function ServerStreamMethod($request, $context)
    {
        echo "处理ServerStreamMethod请求\n";
        
        // 发布事件
        $eventBus = EventBus::getInstance();
        $event = new Event('service.stream_start', [
            'method' => 'ServerStreamMethod',
            'count' => $request->getCount() ?? 5,
        ]);
        $eventBus->publish($event);
        
        $count = $request->getCount() ?? 5;
        
        // 模拟流式响应
        for ($i = 0; $i < $count; $i++) {
            // $response = new Helloworld\StreamResponse();
            // $response->setMessage("Stream message $i");
            // $context->write($response);
            
            echo "发送流式响应 $i\n";
            usleep(100000); // 100ms延迟
        }
        
        // 发布事件
        $event = new Event('service.stream_end', [
            'method' => 'ServerStreamMethod',
            'count' => $count,
        ]);
        $eventBus->publish($event);
    }
    
    /**
     * 双向流方法
     */
    public function BidirectionalStreamMethod($context)
    {
        echo "处理BidirectionalStreamMethod请求\n";
        
        // 发布事件
        $eventBus = EventBus::getInstance();
        $event = new Event('service.bidirectional_stream_start', [
            'method' => 'BidirectionalStreamMethod',
        ]);
        $eventBus->publish($event);
        
        // 读取请求并写入响应
        // while ($request = $context->read()) {
        //     $response = new Helloworld\StreamResponse();
        //     $response->setMessage("Echo: " . $request->getMessage());
        //     $context->write($response);
        // }
        
        echo "双向流处理完成\n";
        
        // 发布事件
        $event = new Event('service.bidirectional_stream_end', [
            'method' => 'BidirectionalStreamMethod',
        ]);
        $eventBus->publish($event);
    }
}

// 示例1: 初始化gRPC服务端
echo "=== 示例1: 初始化gRPC服务端 ===\n";

// 获取gRPC管理器实例
$manager = GrpcManager::getInstance();

// 初始化gRPC扩展包
$config = [
    'server' => [
        'host' => '0.0.0.0',
        'port' => 50051,
        'credentials' => null,
    ],
    'connection_pool' => [
        'max_connections' => 10,
        'max_lifetime' => 300,
    ],
    'serialization' => [
        'pool_enabled' => true,
        'cache_enabled' => true,
    ],
    'memory' => [
        'memory_limit' => 100 * 1024 * 1024, // 100MB
        'monitoring_enabled' => true,
    ],
    'event' => [
        'history_enabled' => true,
        'max_history_size' => 100,
    ],
];

$manager->initialize($config);

echo "gRPC服务端初始化完成\n";

// 示例2: 注册服务
echo "\n=== 示例2: 注册服务 ===\n";

// 注册服务
\WebmanGrpc\Grpc::registerService('example.ExampleService', ExampleService::class);

echo "服务注册完成\n";

// 示例3: 添加拦截器
echo "\n=== 示例3: 添加拦截器 ===\n";

// 添加拦截器
\WebmanGrpc\Grpc::addInterceptor(LoggingInterceptor::class, 100);

echo "拦截器添加完成\n";

// 示例4: 添加事件监听器
echo "\n=== 示例4: 添加事件监听器 ===\n";

// 获取事件总线
$eventBus = $manager->getEventBus();

// 添加事件监听器
$eventListener = new ServiceEventListener();
$eventBus->addListener('service.request', $eventListener);
$eventBus->addListener('service.stream_start', $eventListener);
$eventBus->addListener('service.stream_end', $eventListener);

echo "事件监听器添加完成\n";

// 示例5: 启动服务端
echo "\n=== 示例5: 启动服务端 ===\n";

// 注意：这里只是演示如何启动服务端，实际使用时需要完整的Webman环境
// 在实际应用中，服务端会在Webman启动时自动启动

echo "准备启动gRPC服务端...\n";
echo "服务地址: 0.0.0.0:50051\n";
echo "注意：这只是演示代码，实际启动需要完整的Webman环境\n";

// 示例6: 性能监控
echo "\n=== 示例6: 性能监控 ===\n";

// 启用性能监控
$manager->enablePerformanceMonitoring();

// 模拟一些请求处理
$monitor = $manager->getPerformanceMonitor();
for ($i = 0; $i < 3; $i++) {
    $requestId = $monitor->startRequest("SimpleMethod", "example.ExampleService", ['request_id' => $i]);
    usleep(50000); // 模拟处理时间
    $monitor->endRequest($requestId, 200, 1024, 2048);
}

// 获取性能数据
$performanceData = $monitor->getPerformanceData();
echo "性能数据: " . json_encode($performanceData, JSON_PRETTY_PRINT) . "\n";

// 示例7: 事件统计
echo "\n=== 示例7: 事件统计 ===\n";

// 获取事件统计
$eventStats = $eventBus->getStats();
echo "事件统计: " . json_encode($eventStats, JSON_PRETTY_PRINT) . "\n";

// 示例8: 综合统计
echo "\n=== 示例8: 综合统计 ===\n";

// 获取所有统计信息
$allStats = $manager->getStats();
echo "综合统计: " . json_encode($allStats, JSON_PRETTY_PRINT) . "\n";

echo "\n服务端示例执行完毕\n";
echo "要在实际环境中运行gRPC服务端，请使用完整的Webman框架\n";